package com.aa.base.log

import android.content.Context
import com.appsflyer.AppsFlyerConversionListener
import com.appsflyer.AppsFlyerLib
import com.aa.base.BaseUtils
import com.aa.base.PlayerCheck
import com.aa.base.event.EventLiveData
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.*

/**
 * @author Afra55
 * @date 4/9/21
 * A smile is the best business card.
 */
object AppsFlyerUtils {

    @JvmStatic
    fun init(applicationContext: Context, key: String, openLog: Boolean, nonOrganic:(String)->Unit) {
        try {
            val conversionDataListener = object : AppsFlyerConversionListener {
                override fun onConversionDataSuccess(data: MutableMap<String, Any>?) {
                    if (PlayerCheck.context == null) {
                        PlayerCheck.context = applicationContext
                    }
                    var ind = ""
                    data?.let { cvData ->
                        cvData.map {
                            AppLog.i("conversion_attribute:  ${it.key} = ${it.value}")
                            if (it.key == "af_status") {
                                val value = it.value

                                val toString = value.toString()
                                if (toString != "null" && toString.isNotEmpty() && toString != "Organic" && toString != "organic") {
                                    ind = toString
                                    PlayerCheck.af_status =
                                        toString.toLowerCase(Locale.getDefault())
                                    trackEvent(applicationContext, "conversion_$toString")
                                    GlobalScope.launch(Dispatchers.Main) {
                                        try {
                                            PlayerCheck.af_status =
                                                toString.toLowerCase(Locale.getDefault())
                                        } catch (e: Exception) {
                                        }
                                        try {
                                            nonOrganic.invoke(toString)
                                        } catch (e: Exception) {
                                        }
                                        try {
                                            EventLiveData.sendEvent("af_status", toString)
                                        } catch (e: Exception) {
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                override fun onConversionDataFail(error: String?) {
                    AppLog.i("error onAttributionFailure :  $error")
                }

                override fun onAppOpenAttribution(data: MutableMap<String, String>?) {
                    data?.map {
                        AppLog.i("onAppOpen_attribute: ${it.key} = ${it.value}")
                    }
                }

                override fun onAttributionFailure(error: String?) {
                    AppLog.i("error onAttributionFailure :  $error")
                }
            }
            AppsFlyerLib.getInstance().setDebugLog(openLog)
            AppsFlyerLib.getInstance().init(key, conversionDataListener, applicationContext)
            start(applicationContext)
        } catch (e: Exception) {
        }
    }

    @JvmStatic
    fun start(applicationContext: Context) {
        try {
            AppsFlyerLib.getInstance().start(applicationContext)
            AppsFlyerLib.getInstance().logSession(applicationContext)
            trackRetentionRate(applicationContext)
        } catch (e: Exception) {
        }
    }

    @JvmStatic
    fun trackAppLaunch(context: Context) {
        AdjustUtil.trackAppLaunch()
        trackEvent(context, "app_launch")
        trackRetentionRate(context)
    }

    @JvmStatic
    fun trackEvent(context: Context, eventName: String, vararg pair: Pair<String, Any>) {

        try {
            val mutableMapOf = mutableMapOf(*pair)
            try {
                val vnVc = BaseUtils.getVersionNameToVersionCode(context)
                mutableMapOf["versionName"] = vnVc.first
                mutableMapOf["versionCode"] = vnVc.second
                mutableMapOf["reason"] = PlayerCheck.af_status
            } catch (e: Exception) {
            }
            AppsFlyerLib.getInstance().logEvent(context, eventName, mutableMapOf)
        } catch (e: Exception) {
        }
    }

    @JvmStatic
    fun trackEvent(context: Context, eventName: String) {

        try {
            val mutableMapOf = mutableMapOf<String, Any>()
            try {
                val vnVc = BaseUtils.getVersionNameToVersionCode(context)
                mutableMapOf["versionName"] = vnVc.first
                mutableMapOf["versionCode"] = vnVc.second
                mutableMapOf["reason"] = PlayerCheck.af_status
            } catch (e: Exception) {
            }
            AppsFlyerLib.getInstance().logEvent(context, eventName, mutableMapOf)
        } catch (e: Exception) {
        }
    }

    @JvmStatic
    fun trackAdSplashShouldShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_splash_should_show")
        AdjustUtil.trackAdSplashShouldShow(from, network)
    }

    @JvmStatic
    fun trackAdSplashRealShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_splash_real_show")
        AdjustUtil.trackAdSplashRealShow(from, network)
    }

    @JvmStatic
    fun trackAdRewardShouldShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_reward_should_show")
        AdjustUtil.trackAdRewardShouldShow(from, network)
    }

    @JvmStatic
    fun trackAdRewardRealShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_reward_real_show")
        AdjustUtil.trackAdRewardRealShow(from, network)
    }
    @JvmStatic
    fun trackAdVideoShouldShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_video_should_show")
        AdjustUtil.trackAdInterstitialShouldShow(from, network)
    }
    @JvmStatic
    fun trackAdVideoRealShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_video_real_show")
        AdjustUtil.trackAdInterstitialRealShow(from, network)
    }
    @JvmStatic
    fun trackAdInterShouldShow(context: Context, from:String, network:String) {
        trackEvent(context, "ad_inter_should_show")
        AdjustUtil.trackAdInterPageShouldShow(from, network)
    }

    @JvmStatic
    fun trackAdInterRealShow(context: Context, from:String, network:String){
        trackEvent(context, "ad_inter_real_show")
        AdjustUtil.trackAdInterPageRealShow(from, network)
    }
    @JvmStatic
    fun trackAppPreEmpty(context: Context){
        trackEvent(context, "app_pre_empty")
        AdjustUtil.trackAppAlive()
    }
    @JvmStatic
    fun trackAppEmptyLaunch(context: Context){
        trackEvent(context, "app_empty_launch")
        AdjustUtil.trackAppAlive()
    }
    @JvmStatic
    fun trackAdScreenShouldShow(context: Context, from:String, network:String) {
        trackEvent(context, "ad_lock_screen_should_show")
        AdjustUtil.trackAdLockScreenShouldShow(from, network)
    }
    @JvmStatic
    fun trackAdScreenRealShow(context: Context, from:String, network:String) {
        trackEvent(context, "ad_lock_screen_real_show")
        AdjustUtil.trackAdLockScreenRealShow(from, network)
    }

    @JvmStatic
    fun trackFunctionUse(context: Context) {
        trackEvent(context, "function_use")
        AdjustUtil.trackFunctionUse()
    }
    @JvmStatic
    fun trackBannerShow(context: Context, from:String, network:String) {
        trackEvent(context, "ad_banner")
        AdjustUtil.trackAdBanner(from, network)
    }

    @JvmStatic
    fun trackRetentionRate(context: Context) {
        AdjustUtil.trackInstallLive(context)
        trackRealRemain(context)
        try {
            val sp = context.getSharedPreferences("retention_rate", Context.MODE_PRIVATE)
            val firstTime = sp.getLong("first_time", 0)
            if (firstTime < 0) {
                // do nothing
            }else if (firstTime == 0L) {
                sp.edit().putLong("first_time", System.currentTimeMillis()).apply()
            } else {

                val lastCld = Calendar.getInstance()
                lastCld.timeInMillis = firstTime
                lastCld.set(Calendar.HOUR_OF_DAY, 0)
                lastCld.set(Calendar.MINUTE, 0)
                lastCld.set(Calendar.SECOND, 0)
                lastCld.set(Calendar.MILLISECOND, 0)
                val lastZero = lastCld.timeInMillis

                val now = System.currentTimeMillis()
                val d = now - lastZero

                if (d >= 86400000 && d <= 2 * 86400000) {

                    trackEvent(context, "retention_rate")
                    AdjustUtil.trackRetentionRate(context)
                    sp.edit().putLong("first_time", -100).apply()
                }

            }
        } catch (e: Exception) {
        }
    }
    @JvmStatic
    fun trackRealRemain(context: Context) {
        try {
            val sp = context.getSharedPreferences("real_retention_rate", Context.MODE_PRIVATE)
            val firstTime = sp.getLong("first_time", 0)
            if (firstTime < 0) {
                // do nothing
            }else if (firstTime == 0L) {
                sp.edit().putLong("first_time", System.currentTimeMillis()).apply()
            } else {

                val now = System.currentTimeMillis()
                val d = now - firstTime

                if (d >= 86400000 && d <= 2 * 86400000) {
                    AdjustUtil.trackRealRetentionRate(context)
                    sp.edit().putLong("first_time", -100).apply()
                }

            }
        } catch (e: Exception) {
        }

    }
}